ShowTable of Contents Data Exchange with the JDBC Resource Adapter
The JDBC Resource Adapter allows for accessing database resources using JDBC driver Java classes. This adapter can be used to -
- Monitor JDBC accessible resources. If matching result sets are found trigger events are published which can kick off ACS Flows for further data processing.
- Read data from and write data to JDBC resources. SQL command(s) can be sent through messages to the Expeditor integrator runtime which are executed on
a given JDBC resource. XML-based data can also be transmitted by the JDBC Adapter.
Supported Data Formats
Data for JDBC resources can be handed over to the JDBC Resource Adapter in different formats. The supported formats are specified in the JMS Custom Header property:
ResourceCmd = { SQL | XPDINTEG_DBXML | XML}
The ResourceCmd defines the way of the creation of the SQL command which needs to be executed.
- SQL – the message payload contains complete valid SQL statements that are transparently passed on to the database. The provided SQL statement must be a valid SQL script (SQL commands separated by ‘;’). The SQL CONNECT and DISCONNECT must not be included since these are created during the Java DB connection. The single SQL commands are passed on as prepared statements.
- XPDINTEG_DBXML– the message payload contains the specific Expeditor integrator database XML structure which contains SQL command section and data section (see Listing 4 in chapter 2.5.2). The same XML format is used for the ResultSet which is sent back in a message (ACS Activity: DBSerializeResourceActivity, see chapter 4.1.3).
- XML – The message payload contains a standard XML document with the standard XML header:
<?xml version="1.0" encoding="UTF-8"?>…
This carries the data to be updated in the database. The Activity context parameters include the SQL (update) statement as well as the columns which need to be selected from the XML document as XPath statements. Example below:
Listing 3: Example configuration for INSERT and UPDATE cases in the MessageToDBXMLActivity (refer to Activity catalogue in ACS Activities)
INSERT:
<XPDintegActivity
Name="MessageToDBXMLActivity"
ActivityName="XPDINTEG_MESSAGE_TO_DB_XML"
SQL="INSERT INTO DB2ADMIN.XML_PAYLOAD(STOREID, WORKSTORE, SEQUENCE_NO, OPERATOR, DATE_TIME, PAYLOAD)
VALUES(?, ?, ?, ?, ?, ?)"
DB_URI="jdbc:db2://dbserver.sample.com:50000/IRIS"
DriverClass="com.ibm.db2.jcc.DB2Driver"
Username="db2admin"
Password="passw0rd"
Column_1="xpath:/poslog:POSLog/poslog:Transaction/poslog:RetailStoreID/text()"
Column_2="xpath:/poslog:POSLog/poslog:Transaction/poslog:WorkstationID/text()"
Column_3="xpath:/poslog:POSLog/poslog:Transaction/poslog:SequenceNumber/text()"
Column_4="xpath:/poslog:POSLog/poslog:Transaction/poslog:OperatorID/text()"
Column_5="xpath:translate(/poslog:POSLog/poslog:Transaction/poslog:EndDateTime/text(), 'T', ' ')"
Column_6="data"
/>
UPDATE:
<XPDintegActivity
Name="MessageToDBXMLActivity"
ActivityName="XPDINTEG_MESSAGE_TO_DB_XML"
SQL="UPDATE DB2ADMIN.XML_PAYLOAD SET STOREID=? WHERE WORKSTORE=?"
Column_1="xpath:/poslog:POSLog/poslog:Transaction/poslog:RetailStoreID/text()"
Column_2="xpath:/poslog:POSLog/poslog:Transaction/poslog:WorkstationID/text()"
/>
Expeditor integrator XML Data Structure for DB Operations
The database command can be provided in the MessagePurpose=DBRecordUpdate/DBRecordSelect message as complete sequence of SQL statements (ResourceCmd = SQL) or in the section of the Expeditor integrator specific XML structure XPDinteg_DBdata_xml_structure (ResourceCmd = XPDINTEG_DBXML). The retrieved Result Set (DatabaseResourceData object) is also transformed into the XPDinteg_DBdata_xml_structure and makes the payload of the result message (see example below).
XPDinteg database data and result set structure XPDinteg_DBdata_xml_structure
<?xml version="1.0" encoding="utf-8" ?>
<!-- COMMAND -->
<database-command>
<!—CREATE TABLE -->
<create table-name="MENU">
<create-clause>NUMBER INTEGER NOT NULL, DESCRIPTION VARCHAR(24) </create-clause>
</create>
….
<!—DROP TABLE -->
<drop table-name="MENU"></drop>
….
<!-- INSERT -->
<insert table-name="tablename">
<column name=”columnname” type=”type”>value</column>
</insert>
….
<!-- UPDATE -->
<update table-name="tablename">
<set-clause>
<column name="columnname" type="type">value</column>
</set-clause>
<where-clause type=string>columnname=value</where-clause>
</update>
….
<!-- UPDATE , INSERT if record does not exists -->
<update_insert table-name="MENU">
<set-clause>
<column name="PRICE" type="expr">PRICE+2</column>
</set-clause>
<where-clause type=”string”>COURSE=”dessert”</where-clause>
<insert table-name="MENU">
<column name=”COURSE” type=”string”>dessert</column>
<column name=”PRICE” type=”int”>5</column>
</insert>
</update_insert></database-command>
….
<!-- SELECT -->
<select table-name="MENU">
<select-clause>*</select-clause>
<where-clause>item=’crème brulee’:type=string AND course=’dessert’:type=string</where-clause>
</select>
<select table-name="MENU">
<select-clause>ITEM,PRICE</select-clause>
<where-clause>item=’crème brulee’:type=string AND course=’dessert’:type=string</where-clause>
</select>
….
</database-command>
<!-- DATA -->
<tables>
<table name=”tablename_1”>
<row>
<column name=”columnname” type=”type”>value</column>
<column name=”columnname” type=”type”>value</column>
…
</row>
<row>
<column name=”columnname” type=”type”>value</column>
<column name=”columnname” type=”type”>value</column>
…
</row>
</table>
<table name=”tablename_2”>
..
</table>
..
</tables>
Note: The XPDinteg_DBdata_xml_structure must be escaped when it is included in the tag of an XML message (see example messages in APPENDIX A – Example Messages).
Supported Datatypes
The XPDinteg_DBdata_xml_structure understands Java data types. These are mapped to SQL data types appropriately (see mapping documentation in http://java.sun.com/j2se/1.3/docs/guide/jdbc/getstart/mapping.html ). The following types are supported in XPDinteg_DBdata_xml_structure:
Table 1: Supported types in XPDinteg_DBdata_xml_structure
Java basic type in XPDinteg_DBdata_xml_structure | SQL type | Comment |
String, Int, double | |
|
Expr | depends on the values provided | Data field contains other variables,e.g. ‘PRICE+0.5’ |
BLOB, CLOB | BLOB, CLOB | (not implemented ) |
DBRecordUpdate Messages
Message Header Properties
The following Custom Message Header properties are available for messages sent from back-end messaging system to Expeditor integrator runtime -
- DestinationPath=DBURI:’’;DRIVER_CLASS:’’
(names contain forward slashes only!)
Example for Derby: DBURI:’jdbc:derby:datatrans/inbound/SampleDb;create=true’;DRIVER_CLASS:’org.apache.derby.jdbc.EmbeddedDriver’
Example for DB2: DBURI:’jdbc:db2://localhost:50000/SampleDb’;DRIVER_CLASS:’com.ibm.db2.jcc.DB2Driver’
- DestinationName=
- Credentials=User:;Password:
- ResourceCmd=SQL | XPDINTEG_DBXML | XML
- SQL – message payload contains SQL command as a string
- XPDINTEG_DBXML – message payload contains (see Listing 4 in Expeditor integrator XML Data Structure for DB Operations)
- XML - The message payload contains a standard XML document with the standard XML header: <?xml version="1.0" encoding="UTF-8"?>…
(see upported Data Formats for JDBC Resource Access)
- DestinationCreationMode=TABLE_CREATE | INSERT | UPDATE | UPDATE_INSERT
- TABLE_CREATE – table is created if not existent
- TABLE_DROP – removes table if it exists
- UPDATE - SQL update (fails if record does not exist)
- INSERT – SQL insert (fails if record exists)
- UPDATE_INSERT – SQL read ahead, if record exists then update it / if record does not exist then insert it
- Payload={string_of_full_sql_statement | }
Example for ResourceCmd=SQL and DestinationCreationMode=TABLE_CREATE:
CREATE TABLE menu(course CHAR(10), item CHAR(20), price INTEGER);
Message examples with SQL statements
Note: The provided SQL commands will be executed by the JDBC Resource Adapter which automatically surrounds them with SQL CONNECT and DISCONNECT statements.
Message examples with WHERE clause and data map
(see )
Table 2: DBRecordUpdate message with WHERE clause (Derby database example)
Custom Msg Header | CREATE / DROP table menu in DB SampleDb | Insert a record in table menu of SampleDb | Update a record in table menu of SampleDb | Update a record; insert if not existent in table menu of SampleDb |
MessagePurpose | DBRecordUpdate | DBRecordUpdate | DBRecordUpdate | DBRecordUpdate |
TransportType | DB | DB | DB | DB |
ResourceType | DBResource | DBResource | DBResource | DBResource |
DestinationPath (example for Derby DB) | DBURI:’jdbc:derby:datatrans/ inbound/SampleDb;create=true’; DRIVER_CLASS:’org.apache.derby. jdbc.EmbeddedDriver’ | DBURI:’jdbc:derby:datatrans/ inbound/SampleDb’; DRIVER_CLASS:’org.apache.derby. jdbc.EmbeddedDriver’ | DBURI:’jdbc:derby:datatrans/ inbound/SampleDb’; DRIVER_CLASS:’org.apache.derby. jdbc.EmbeddedDriver’ | DBURI:’jdbc:derby:datatrans/inbound/ SampleDb’; DRIVER_CLASS:’org.apache.derby. jdbc.EmbeddedDriver’ |
DestinationName | menu | menu | menu | menu |
Credentials | User:dbuser;Password:dbpasswd | User:dbuser;Password:dbpasswd | User:dbuser;Password:dbpasswd | User:dbuser;Password:dbpasswd |
ResourceCmd | SQL | SQL | SQL | SQL |
DestinationCreationMode | | INSERT | UPDATE | UPDATE_INSERT |
Payload == Executed SQL statements
(Payload contains any JDBC prepared statement w/o CONNECT and DISCONNECT)
| For table creation:
CREATE TABLE menu(course CHAR(10), item CHAR(20), price INTEGER);
For table deletion:
DROP TABLE menu;
| INSERT INTO menu VALUES ('appetizer','baby greens',7);
INSERT INTO menu VALUES ('entree','lamb chops ',6);
INSERT INTO menu VALUES ('dessert','creme brulee',14);
| UPDATE menu SET price = price + 5 WHERE course='appetizer';
UPDATE menu SET price = price - 1 WHERE course='entree';
UPDATE menu SET price = price + 2 WHERE course='dessert';
| UPDATE menu SET price = price + 5 WHERE course='appetizer1';
INSERT INTO menu VALUES('appetizer1','baby greens1',5)
2 separate steps:
a) UPDATE menu SET price = price + 5 WHERE course='appetizer1';
If UPDATE fails then
b) INSERT INTO menu VALUES('appetizer1','baby greens1',5)
|
Comment | Sequence of SQL commands (e.g. SQL script) will be executed in separate prepared statements | Fails if table does not exist | Fails if record with course=appetizer does not exists | Inserts new record if not exists |
Note: The provided SQL commands will be executed by the JDBC Resource Adapter which automatically surrounds them with SQL CONNECT and DISCONNECT statements.
Example XML message which explain how the is used within XML messages.
XML example included in the payload of the TABLE_CREATE message (according to the XPDinteg_DBdata_xml_structure)
<?xml version="1.0" encoding="utf-8" ?>
<!-- COMMAND -->
<database-command>
<create table-name="menu">
<create-clause>course CHAR(10), item CHAR(20), price INTEGER</create-clause>
</create>
</database-command>
<!-- DATA -->
Note: This data structure must be escaped within the tag of an XML message. Listing 6 shows the tag snippet of an example XML message which includes the in its payload. Only white spaces should be used (e.g. no tabs) within in the payload.
Example #1: example for creating table menu (snippet for tag of XML message)
…
<text>
<?xml version="1.0" encoding="utf-8" ?>
<!-- COMMAND -->
<database-command>
<create table-name="menu">
<create-clause>course CHAR(10), item CHAR(20), price INTEGER</create-clause>
</create>
</database-command>
<!--DATA -->
</text>
…
The price data field could also be of type double (e.g. course CHAR(10), item CHAR(20), price DOUBLE)
Listing 7: XML example included in the payload of the TABLE_DROP message (according to the XPDinteg_DBdata_xml_structure as snippet for tag of XML message)
…
<text>
<?xml version="1.0" encoding="utf-8" ?>
<!-- COMMAND -->
<database-command>
<drop table-name="menu"></drop>
</database-command>
<!--DATA -->
</text>
…
Example #2: XML example included in the payload of the INSERT message (according to the XPDinteg_DBdata_xml_structure)
<?xml version="1.0" encoding="utf-8" ?>
<!-- COMMAND -->
<database-command>
<insert table-name="menu">
<column name=”course” type=”string”>appetizer</column>
<column name=”item” type=”string”>baby greens</column>
<column name=”price” type=”int”>7</column>
</insert>
<insert table-name="menu">
<column name=”course” type=”string”>entree</column>
<column name=”item” type=”string”>lamb chops</column>
<column name=”price” type=”int”>6</column>
</insert>
<insert table-name="menu">
<column name=”course” type=”string”>dessert</column>
<column name=”item” type=”string”>creme brulee</column>
<column name=”price” type=”int”>14</column>
</insert>
</database-command>
<!-- DATA -->
Example #3: XML example for data included in the payload of the UPDATE message (according to the XPDinteg_DBdata_xml_structure)
<?xml version="1.0" encoding="utf-8" ?>
<!-- COMMAND -->
<database-command>
<update table-name="menu">
<set-clause>
<column name="price" type="expr">price+2</column>
</set-clause>
<where-clause type=”string”>course=’dessert’</where-clause>
</update>
</database-command>
<!-- DATA -->
Note: Multiple updates must be enclosed in separate tags. Multiple statements can belong to one .
Example #4: example for creating table menu (snippet for tag of XML message)
…
<text>
<?xml version="1.0" encoding="utf-8" ?>
<!-- COMMAND -->
<database-command>
<update table-name="menu">
<set-clause>
<column name="price" type="expr">price+2</column>
</set-clause>
<where-clause type="string">course='dessert'</where-clause>
</update>
</database-command>
<!--DATA -->
</text>
…
Example #5: XML example for data included in the payload of the UPDATE_INSERT message (according to the XPDinteg_DBdata_xml_structure)
<?xml version="1.0" encoding="utf-8" ?>
<!-- COMMAND -->
<database-command>
<update_insert table-name="menu">
<set-clause>
<column name="price" type="expr">price+3</column>
</set-clause>
<where-clause type=”string”>course=’dessert’</where-clause>
<insert table-name="menu">
<column name=”course” type=”string”>dessert</column>
<column name=”item” type=”string”>apfelstrudel</column>
<column name=”price” type=”int”>3</column>
</insert>
</update_insert>
</database-command>
<!-- DATA -->
DBRecordSelect Messages
Message Header Properties
The following Custom Message Header properties are available for messages sent from back-end messaging system to Expeditor integrator runtime (see Table 3 in Supported Custom Header Properties for Inbound Messages also):
- DestinationPath=DBURI:’’;DRIVER_CLASS:’’
(names contain forward slashes only!)
Example for Derby: DBURI:’jdbc:derby:datatrans/inbound/SampleDb;create=true’;DRIVER_CLASS:’org.apache.derby.jdbc.EmbeddedDriver’
Example for DB2: DBURI:’jdbc:db2://localhost:50000/SampleDb’;DRIVER_CLASS:’com.ibm.db2.jcc.DB2Driver’
- DestinationName=
- Credentials=User:;Password:
- ResourceCmd=SQL | XPDINTEG_DBXML | XML
- SQL – message payload contains SQL command as a string
- XPDINTEG_DBXML – message payload contains (see Error! Reference source not found in Expeditor integrator XML Data Structure for DB Operations)
- DestinationCreationMode=not used
- Payload=
Note: The message payload will only support the XPDinteg_DBdata_xml_structure by default (see Error! Reference source not found. in chapter 2.5.2). For customization purposes, this structure could be transformed into another (XML) structure by adding a custom ACS Activity to the DbRecordSelect flow:
DBCustomDataTransformer: general extendable Activity which transforms XPDinteg_DBdata_xml_structure into customer’s specific XML format
Message examples for DBRecordSelect
Messages from the back-end messaging system can carry queries for database resources. The result set is created and is sent back to the messaging back-end within defined DBRecordSelect messages (see Table 4 in chapter 2.4.3).
Table 3 shows an example for selecting records from table menu of Derby database SampleDb.
Table 3: Derby DB examples for DBRecordSelect messages and corresponding SQL statements
Custom Msg Header FOR:
Select record(s) in table menu of SampleDb
| SQL statement provided in Payload | WHERE clause provided |
MessagePurpose | DBRecordSelect | DBRecordSelect |
TransportType | DB | DB |
ResourceType | DBResource | DBResource |
DestinationPath | DBURI:’jdbc:derby:datatrans/ inbound/SampleDb’; DRIVER_CLASS:’org.apache.derby. jdbc.EmbeddedDriver’ | DBURI:’jdbc:derby:datatrans/ inbound/SampleDb’; DRIVER_CLASS:’org.apache.derby. jdbc.EmbeddedDriver’ |
DestinationName | menu | menu |
Credentials | User:dbuser;Password:dbpasswd | User:dbuser;Password:dbpasswd |
ResourceCmd | SQL | XPDINTEG_DBXML |
DestinationCreationMode | - | - |
Payload | SELECT * from menu; | |
Executed SQL statements | CONNECT 'jdbc:derby:datatrans\inbound\SampleDb;
SELECT * from menu;
DISCONNECT;
| CONNECT 'jdbc:derby:datatrans\inbound\SampleDb;
SELECT * from menu;
DISCONNECT;
|
Comment | Fails if table does not exist. Returns null / 0 ResultSet if no matching record is available.
Result set is later assembled in the SerializedDBResultSetActivity, see Listing_5 (the interpreted selector clause is also included for reference)
| Fails if table does not exist. Returns null / 0 ResultSet if no matching record is available.
Result set is later assembled in the SerializedDBResultSetActivity, see Listing 14 (the interpreted selector clause is also included for reference)
|
Example #1: <SELECT_SAMPLE_DATA> example for record data included in the message payload (according to the <XPDinteg_DBdata_xml_structure>)
<?xml version="1.0" encoding="utf-8" ?>
<!-- COMMAND -->
<database-command>
<select table-name="menu">
<select-clause>*</select-clause>
<where-clause>item=”creme brulee” AND course=”dessert”</where-clause>
</select>
...more select elements if required…
</database-command>
<!-- DATA -->
Note: This data structure must be escaped within the tag of an XML message. Listing 13 shows the tag snippet of an example XML message which will trigger the creation of a reply message that contains the ResultSet as in its payload.
Example #2: example for selecting record(s) from table menu (snippet for tag of DBRecordSelect XML message)
<text><?xml version="1.0" encoding="utf-8" ?>
<!-- COMMAND -->
<database-command>
<select table-name="menu">
<select-clause>*</select-clause>
<where-clause>item='creme brulee' AND course='dessert'</where-clause>
</select>
</database-command>
<!--DATA -->
</text>
</text>
Example #3: for record data included in the reply message payload (according to the )
<?xml version="1.0" encoding="utf-8" ?>
<tables>
<table name=”menu”>
<row>
<column name=”course” type=”string”>dessert</column>
<column name=”item” type=”string”>creme brulee</column>
<column name=”price” type=”int”>14</column>
</row>
</table>
</tables>
Using third party drivers for use within integrator
Pre installation steps
For using third-party drivers, e.g: ORACLE 9i Release 2 drivers, follow these steps:
- Create Lotus Expeditor Client-Services Project using the Project Wizard (or an Eclipse plug-in project), e.g. com.ibm.rcp.integrator.oracle.driver. Import the driver JAR files for the customer database on project root level (e.g: ojdbc14.jar) .
- Use provided default settings (no additional plug-in properties set)
- Select Core Target as target platform and the offered Target Features
- No additional Target template selected
- Include the imported database driver (JAR file) in the plug-in CLASSPATH. Edit the MANIFEST.MF file and select the Runtime tab.
- Add the JAR to the CLASSPATH section.
- In the Exported Packages section, export all the packages included in the JAR.
- Create an Eclipse Feature Project, e.g. by using the project wizard (name com.ibm.rcp.integrator.oracle.driver.feature). Include the plug-in created above in the feature. Set the colocation-affinity of the feature to com.ibm.rcp.platform.feature (Go to the Installation tab and provide the feature ID com.ibm.rcp.platform.feature in the “To collocate this feature with another feature” field.).
- Create an Update Site Project (e.g. by using the project wizard). Edit the site.xml file and add the generated feature. Build the update site by clicking on Build All. Export the created update site to the file system.
- Include the created feature and plug-in of the created update site folder in the Expeditor integrator installer:
- Copy the feature jar into updates/platform/features and plug-in into updates/platform/plugins folders respectively of the Expeditor integrator installer.
- Add the feature to the site.xml in updates/site.xml:
- Update the install manifest file, e.g. desktop/install/deploy/install.xml:
\
- Other installation options options:
- For installation after deployment, the Expeditor Client Manager could be used to install this feature.
- For manual installation in an existing Expeditor integrator instance, the Provisioning API could be used, e.g. by entering the following command in the OSGi console window:
prov ie file:c://site.xml
where file:/ points to the site.xml in the exported update site above.
(e.g. prov ie com.ibm.rcp.integrator.oracle.driver.feature 1.0.0 file:/c:/tmp/site.xml)
Note: In this case, Expeditor integrator must be re-started for this change to take effect.
Post installation steps
Use the appropriate Expeditor integrator property DestinationPath for providing the database driver name:
DBURI:'jdbc:oracle:thin:@<hostname>:<port>:<dbname>';DRIVER_CLASS:'oracle.jdbc.OracleDriver'
Please, also remember to provide the correct credentials in the Credentials property.
|